package com.desginer.create.strategy;

/**
 * 在Spring Boot应用中，`@Resource`注解标注的`List<RuleProcessorStrategy> ruleProcessorStrategyList`能够在应用启动时自动注入所有`RuleProcessorStrategy`接口的实现类实例，这主要基于Spring框架的依赖注入机制和自动装配原理。以下是其工作原理的详细说明：
 *
 * ---
 *
 * ### 1. **`@Resource`注解的作用**
 * `@Resource`是Java标准的注解（JSR-250），Spring支持通过它实现依赖注入。默认情况下：
 * - **按名称匹配**：如果没有指定`name`属性，则按字段名（`ruleProcessorStrategyList`）查找Bean。
 * - **按类型匹配**：如果按名称找不到Bean，Spring会尝试注入与字段类型（`List<RuleProcessorStrategy>`）匹配的所有Bean。
 *
 * 在用户代码中，由于未指定`name`，Spring会按类型注入所有`RuleProcessorStrategy`的实现类。
 *
 * ---
 *
 * ### 2. **Spring的自动装配机制**
 * Spring Boot启动时，会扫描所有被`@Component`及其派生注解（如`@Service`、`@Repository`等）标记的类。对于`RuleProcessorStrategy`接口：
 * - **收集实现类**：Spring会找到所有实现`RuleProcessorStrategy`接口的类，并将它们的实例注册为Bean。
 * - **注入集合**：当遇到`List<RuleProcessorStrategy>`类型的字段时，Spring会自动将这些Bean组装成一个`List`注入。
 *
 * ---
 *
 * ### 3. **泛型类型`List<T>`的特殊处理**
 * Spring对泛型集合类型（如`List<T>`、`Map<K,V>`）有特殊支持：
 * - **匹配泛型参数**：Spring会检查泛型参数类型（`RuleProcessorStrategy`），并注入所有匹配该类型的Bean。
 * - **动态组装集合**：即使没有显式定义`List<RuleProcessorStrategy>`的Bean，Spring也会在运行时动态创建一个包含所有匹配Bean的集合。
 *
 * ---
 *
 * ### 4. **条件与验证**
 * 确保注入成功的必要条件：
 * 1. **实现类必须被Spring管理**：所有`RuleProcessorStrategy`的实现类需标记为`@Component`（或其他Spring注解）。
 *    ```java
 *    @Service
 *    public class StrategyA implements RuleProcessorStrategy { ... }
 *
 *    @Repository
 *    public class StrategyB implements RuleProcessorStrategy { ... }
 *    ```
 * 2. **无歧义性**：如果存在多个同类型的Bean，但字段名（`ruleProcessorStrategyList`）不匹配任何Bean名称，Spring会优先按类型注入集合。
 *
 * ---
 *
 * ### 5. **对比`@Autowired`**
 * `@Resource`与`@Autowired`的区别：
 * - `@Autowired`默认按类型注入，且支持`@Qualifier`细化Bean。
 * - `@Resource`默认按名称注入，更符合Java标准。在用户代码中，两者效果相同，因为最终都按类型匹配了集合。
 *
 * ---
 *
 * ### 6. **启动流程示例**
 * 1. **扫描组件**：Spring Boot启动时扫描`com.hnair.jasper`包（或相关路径）。
 * 2. **注册Bean**：发现`RuleProcessorStrategy`的实现类，如`StrategyA`、`StrategyB`，将它们注册为Bean。
 * 3. **注入依赖**：在创建`RuleProcessorFactory`实例时，检测到`@Resource`注解，自动将`StrategyA`和`StrategyB`组装成`List`注入到`ruleProcessorStrategyList`字段。
 *
 * ---
 *
 * ### 总结
 * 用户代码中的`List<RuleProcessorStrategy>`能自动注入数据，是因为：
 * 1. Spring收集了所有`RuleProcessorStrategy`的实现类Bean。
 * 2. 通过`@Resource`（或`@Autowired`）的按类型注入机制，动态组装了这些Bean到集合中。
 * 3. 整个过程由Spring的依赖注入容器在启动时自动完成，无需手动配置。
 *
 *
 * @Slf4j
 * @Component
 * public class RuleProcessorFactory {
 *     @Resource
 *     private List<RuleProcessorStrategy> ruleProcessorStrategyList;
 *
 *     private final Map<String, RuleProcessorStrategy> ruleProcessorStrategyMap = new HashMap<>();
 *
 *     @PostConstruct
 *     public void init() {
 *         ruleProcessorStrategyList.forEach(ruleProcessorStrategy -> {
 *             RuleProcessorAnnotation ruleProcessorAnnotation = AnnotationUtils.findAnnotation(ruleProcessorStrategy.getClass(), RuleProcessorAnnotation.class);
 *             if (ruleProcessorAnnotation != null) {
 *                 ruleProcessorStrategyMap.put(ruleProcessorAnnotation.key(), ruleProcessorStrategy);
 *             }
 *         });
 *     }
 *
 *     public RuleProcessorStrategy getProcessStrategy(String key) {
 *         return ruleProcessorStrategyMap.get(key);
 *     }
 * }
 *
 *@Component
 * @RuleProcessorAnnotation(key = RuleProcessorKey.IDENTITY_CODE)
 * public class IdentityRuleProcessor extends AbstractRuleProcessor {
 * }
 *
 *@Component
 * @RuleProcessorAnnotation(key = RuleProcessorKey.ORDER_CODE)
 * public class OrderRuleProcessor extends AbstractRuleProcessor {
 * }
 */
public class StrategyTest {
    public static void main(String[] args) {
        /**
         * 策略模式服务类
         * 定义通用接口
         * 抽象类实现接口，定义流程策略，定义通用流程的抽象方法
         */
        BusinessFlowStrategyFactory factory = new BusinessFlowStrategyFactory();

        BusinessFlowStrategy orderStrategy = factory.getStrategy(BusinessFlow.ORDER);
        orderStrategy.execute();

        factory.getStrategy(BusinessFlow.PAYMENT).execute();


    }
}
